import sys
import logging

from optparse import OptionParser

from flvlib3 import __versionstr__
from flvlib3 import tags
from flvlib3 import helpers
from flvlib3.astypes import MalformedFLV

log = logging.getLogger('flvlib3.debug-flv')
log.setLevel(logging.ERROR)

import traceback

def debug_file(filename, quiet=False, peruse = False, metadata=False,header=False):
    try:
        f = open(filename, 'rb')
    except IOError as xxx_todo_changeme:
        (errno, strerror) = xxx_todo_changeme.args
        log.error("Failed to open `%s': %s", filename, strerror)
        return False

    flv = tags.FLV(f,header=header,peruse=peruse)

    if not quiet:
        print(("=== `%s' ===" % filename))

    try:
        tag_generator = flv.iter_tags()
        # it does not continue to run. will exit.
        for i, tag in enumerate(tag_generator):
            if quiet:
                # If we're quiet, we just want to catch errors
                continue
            # Print the tag information
            print(("#%05d %s" % (i + 1, tag)))
            # Print the content of onMetaData tags
            if (isinstance(tag, tags.ScriptTag)
                and tag.name == "onMetaData"):
                helpers.pprint(tag.variable)
                if metadata:
                    return True
    except MalformedFLV as e:
#        message = str(e)
        if not header:
            log.error("The file `%s' is not a valid FLV file:",
                      filename)
            traceback.print_exc()
#        print(message)
            return False
    except tags.EndOfFile:
        log.error("Unexpected end of file on file `%s'", filename)
        return False

    f.close()

    return True


def process_options():
    usage = "%prog [options] files ..."
    description = ("Checks FLV files for comformance with the FLV "
                   "specification. Outputs a list of tags and, "
                   "if present, the content of the onMetaData script tag.")
    version = "%%prog flvlib3 %s" % __versionstr__
    parser = OptionParser(usage=usage, description=description,
                          version=version)
    parser.add_option("-s", "--strict", action="store_true",
                      help="be strict while parsing the FLV file")
    parser.add_option("-q", "--quiet", action="store_true",
                      help="do not output anything unless there are errors")
    parser.add_option("-f", "--filter", type=str, dest="filter",
                      help="filter tags in regex (can use multiple -f flags)")
    parser.add_option("-k", "--smart", action="store_true", dest="smart",
                      help="smart filter tags (monotonic)")
    parser.add_option("-g", "--inv_filter", type=str, dest="inv_filter",
                      help="inverse filter tags in regex (can use multiple -g flags)")
    parser.add_option("-u", "--peruse", action="store_true", dest="peruse",
                      help="read byte by byte while finding potential tags")
    parser.add_option("-p", "--repair", type=str, dest="repair",
                      help="try to repair and write to the given directory")
    parser.add_option("-r", "--reference", type=str, dest="reference",
                      help="filter out invalid tags with reference flv file")
    parser.add_option("-i", "--ihr", action="store_true",dest="header",
                      help="ignore header errors")
    parser.add_option("-m", "--metadata", action="store_true",
                      help="exit immediately after printing an onMetaData tag")
    parser.add_option("-v", "--verbose", action="count",
                      default=0, dest="verbosity",
                      help="be more verbose, each -v increases verbosity")
    options, args = parser.parse_args(sys.argv)

    if len(args) < 2:
        parser.error("You have to provide at least one file path")

    if options.strict:
        tags.STRICT_PARSING = True

    if options.verbosity > 3:
        options.verbosity = 3

    level = ({0: logging.ERROR, 1: logging.WARNING,
              2: logging.INFO, 3: logging.DEBUG}[options.verbosity])
    logging.getLogger('flvlib3').setLevel(level)

    return options, args


def debug_files():
    options, args = process_options()

    clean_run = True

    for filename in args[1:]:
        if not debug_file(filename, quiet = options.quiet, metadata = options.metadata,peruse=options.peruse, header=options.header):
            clean_run = False

    return clean_run


def main():
    try:
        outcome = debug_files()
    except KeyboardInterrupt:
        # give the right exit status, 128 + signal number
        # signal.SIGINT = 2
        sys.exit(128 + 2)
    except EnvironmentError as xxx_todo_changeme1:
        (errno, strerror) = xxx_todo_changeme1.args
        try:
            print(strerror)
        except Exception:
            pass
        sys.exit(2)

    if outcome:
        sys.exit(0)
    else:
        sys.exit(1)
